package com.ruoyi.framework.websocket;


import com.alibaba.fastjson.JSONObject;
import com.ruoyi.framework.security.service.SysLoginService;
import com.ruoyi.project.applet.domain.Record;
import com.ruoyi.project.applet.service.InteractService;
import com.ruoyi.project.applet.service.RecordService;
import com.ruoyi.project.system.service.ISysUserWxService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@ConditionalOnClass(value = WebSocketConfig.class)
@ServerEndpoint(value = "/ws/{userId}")
@Component
public class WebSocketServer {

    private static final Logger log = LoggerFactory.getLogger(SysLoginService.class);

    // 静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineNum = new AtomicInteger();

    //  这里使用静态，让 service 属于类
    private static RecordService recordService;


    // 注入的时候，给类的 service 注入
    @Autowired
    public void setChatService(RecordService recordService) {
        WebSocketServer.recordService = recordService;
    }


    private static ISysUserWxService accountService;

    @Autowired
    public void setAccountService(ISysUserWxService accountService) {
        WebSocketServer.accountService = accountService;
    }

    private static InteractService lisuService;

    @Autowired
    public void setLisuService(InteractService lisuService) {
        WebSocketServer.lisuService = lisuService;
    }

    // concurrent包的线程安全Set，用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<Integer, Session> sessionPools = new ConcurrentHashMap<>();

    private Integer u_id = 0;

    // 发送消息
    public void sendMessage(Session session, Object object, Integer u_id) throws IOException {
        if (session != null) {//是否在线
            List<Record> records = recordService.selectByIssend(u_id);
            for (int i = 0; i < records.size(); i++) {
                Record record = records.get(i);
                Integer r_id = Math.toIntExact(record.getRecordId());//id
                recordService.updateById(r_id);//通过id修改消息为已发送
            }
            synchronized (session) {
                System.out.println(1);
                session.getBasicRemote().sendText(String.valueOf(object));
            }
        }
    }

    // 给指定用户发送信息  ,Integer from
    public void sendInfo(Integer id, Integer from, String content, Integer content_type, String time) {
        Session session = sessionPools.get(id);
        JSONObject jsonObject = new JSONObject();//创建一个json对象
        jsonObject.fluentPut("type", "msg");
        jsonObject.fluentPut("content", content);
        jsonObject.fluentPut("from", from);
        jsonObject.fluentPut("to", id);
        jsonObject.fluentPut("content_type", content_type);
        jsonObject.fluentPut("time", time);
        try {
            sendMessage(session, jsonObject, id);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userId") Integer uId) {
        HttpServletRequest request = null;
//        String open_id = wx.getopen_id(request);
//        HttpSession session1= (HttpSession)
//                config.getUserProperties().get(HttpSession.class.getName());
//        Long uId= (Long) session1.getAttribute("accountId");//获取当前用户的id
        u_id = Math.toIntExact(uId);
        log.info("是否存在：" + sessionPools.containsKey(u_id));
        if (sessionPools.containsKey(u_id) == true) {
            //再连接池里
            sessionPools.remove(u_id);//关闭连接
            subOnlineCount();
            log.info(onlineNum + "人");
            sessionPools.put(u_id, session);
            addOnlineCount();

        } else {
            //没有再连接池里
            sessionPools.put(u_id, session);
            addOnlineCount();
            log.info(u_id + "加入webSocket！当前人数为" + onlineNum);
        }

        //查询当前用户所有未接受到的消息
        if (recordService.selectByIssend(u_id) == null || recordService.selectByIssend(u_id).size() == 0) {
            //没有未读消息
            System.out.println("没有未读消息，没有未读消息");
        } else {
            List<Record> records = recordService.selectByIssend(u_id);
            for (int i = 0; i < records.size(); i++) {
                JSONObject jsonObject = new JSONObject();//创建一个json对象
                Record record = records.get(i);
                Integer from = Math.toIntExact(record.getFromId());//谁发送的
                Integer to = Math.toIntExact(record.getToId());//发给谁的
                String content = record.getRecordContent();//消息内容
                Long content_type = record.getRecordType();//消息类型
                Date time = record.getCreateTime();//发送时间
                Integer r_id = Math.toIntExact(record.getRecordId());//id
                jsonObject.fluentPut("type", "msg");
                jsonObject.fluentPut("content", content);
                jsonObject.fluentPut("from", from);
                jsonObject.fluentPut("to", to);
                jsonObject.fluentPut("content_type", content_type);
                jsonObject.fluentPut("time", time);
                //jsonArray.add(jsonObject);//存进数组
                recordService.updateById(r_id);//通过id修改消息为已发送
                try {
                    sendMessage(session, jsonObject, u_id);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 关闭连接时调用
    @OnClose
    public void onClose() {
        log.info("关闭连接u_id:" + u_id);
        if (null == u_id) {

        } else {
            sessionPools.remove(u_id);
            subOnlineCount();
            log.info(u_id + "断开webSocket连接！当前人数为" + onlineNum);
        }

    }

    // 收到客户端信息throws   HttpServletRequest request = null;
    @OnMessage
    public void onMessage(String ss) throws IOException {
        System.out.println("ss:" + ss);
        try {
            JSONObject jsonObject = JSONObject.parseObject(ss);//转json
            if (null == u_id) {
                //用户没有注册
            } else {
                if (jsonObject.getString("type").equals("msg") || jsonObject.getString("type") == "msg") {
                    //第一种类型，发送消息
                    if (null == jsonObject.getInteger("to")) {
                        //操作错误
                    } else {
                        Integer u_id1 = jsonObject.getInteger("to");
                        String content = jsonObject.getString("content");
                        Integer content_type = jsonObject.getInteger("content_type");
//                        Integer from = jsonObject.getInteger("from");
                        SimpleDateFormat sdf = new SimpleDateFormat();// 格式化时间
                        sdf.applyPattern("yyyy-MM-dd HH:mm:ss");// a为am/pm的标记
                        Date date = new Date();
                        String time = sdf.format(date);

                        long count = recordService.isrecord(u_id, u_id1);
                        long count1 = recordService.isrecord(u_id1, u_id);
                        String chatid = null;
                        if (count == 0 && count1 == 0) {//俩人第一次聊天
                            //获取随机字符串   会话id
                            String str = "0123456789abcdefghijklmnopqrstuvwxyz";
                            Random random = new Random();
                            StringBuffer sb = new StringBuffer();
                            for (int i = 0; i < 3; i++) {
                                int number = random.nextInt(10);
                                sb.append(str.charAt(number));
                            }
                            chatid = sb + String.valueOf(u_id) + String.valueOf(u_id1);
                            recordService.add(u_id, u_id1, content, content_type, chatid, time);//添加消息记录
                            if (content_type == 2) {
                                //内容是图片
                                lisuService.add(u_id, u_id1, 1, time, "[图片]", content_type, chatid);//添加聊天列表
                                lisuService.add(u_id1, u_id, 0, time, "[图片]", content_type, chatid);
                            } else {
                                lisuService.add(u_id, u_id1, 1, time, content, content_type, chatid);//添加聊天列表
                                lisuService.add(u_id1, u_id, 0, time, content, content_type, chatid);
                            }
                        } else {
                            //俩人不是第一次聊天
                            chatid = lisuService.isrecord(u_id, u_id1).getChatId();//获取两个人的会话id
                            recordService.add(u_id, u_id1, content, content_type, chatid, time);//添加消息记录
                            Integer l_count = Math.toIntExact(lisuService.isrecord(u_id, u_id1).getCount());//获取当前唯独条数
                            Integer l_count1 = Math.toIntExact(lisuService.isrecord(u_id1, u_id).getCount());//获取当前唯独条数
                            if (content_type == 2) {
                                //内容是图片
                                lisuService.update(u_id, u_id1, l_count + 1, time, "[图片]", content_type);//修改聊天列表
                                lisuService.update(u_id1, u_id, l_count1, time, "[图片]", content_type);
                            } else {
                                lisuService.update(u_id, u_id1, l_count + 1, time, content, content_type);//修改聊天列表
                                lisuService.update(u_id1, u_id, l_count1, time, content, content_type);//修改聊天记录
                            }
                        }
                        sendInfo(u_id1, u_id, content, content_type, time);
                    }
                } else {
                    //第二种类型,反馈类型，用户点进聊天框   ,from
                    Integer u_id1 = jsonObject.getInteger("account");
//                    Integer from = jsonObject.getInteger("from");
                    recordService.updateread(u_id1, u_id);//修改为已读
                    lisuService.updatecount(u_id1, u_id);//修改用户列表未读为0
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            log.error("出错啦" + e.getMessage());
        }
    }

    // 错误时调用
    @OnError
    public void onError(Session session, Throwable throwable) {
        log.info("发生错误" + throwable.getMessage());
        throwable.printStackTrace();
    }

    public static void addOnlineCount() {
        onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineNum.decrementAndGet();
    }

}

